package main

import (
	"fmt"
	"math"
)

type coordinate struct {
	d, m, s float64
	h       rune
}

type Rovers struct {
	name, site string
	lat, lon   float64
}

type world struct {
	radius float64
}

func (c coordinate) decimal() float64 {
	sign := 1.0
	switch c.h {
	case 'S', 'W', 's', 'w':
		sign = -1
	}
	return sign * (c.d + c.m/60 + c.s/3600)
}

func initRovers(name, site string, lat, long coordinate) Rovers {
	return Rovers{name: name, site: site, lat: lat.decimal(), lon: long.decimal()}
}

func (w world) distance(p1, p2 Rovers) float64 {
	s1, c1 := math.Sincos(rad(p1.lat))
	s2, c2 := math.Sincos(rad(p2.lat))
	clong := math.Cos(rad(p1.lon - p2.lon))
	return w.radius * math.Abs(s1*s2+c1*c2*clong)
}

func rad(deg float64) float64 {
	return deg * math.Pi / 180
}

func main() {
	mars := world{radius: 3389.5}
	landers := []Rovers{
		initRovers("spirit", "cms", coordinate{14, 34, 6.2, 's'}, coordinate{175, 28, 21.5, 'e'}),
		initRovers("opp", "ch", coordinate{1, 56, 46.3, 's'}, coordinate{354, 28, 24.2, 'e'}),
		initRovers("cur", "bl", coordinate{4, 35, 22.2, 's'}, coordinate{137, 26, 30.1, 'e'}),
		initRovers("insight", "ely", coordinate{4, 30, 0.0, 'n'}, coordinate{135, 54, 0, 'e'}),
	}
	var dist float64
	max := float64(math.MinInt)
	min := float64(math.MaxInt)
	var maxL, minL string
	for i := 0; i < len(landers)-1; i++ {
		for j := i + 1; j < len(landers); j++ {
			dist = mars.distance(landers[i], landers[j])
			if dist > max {
				max = dist
				maxL = landers[i].name + " " + landers[j].name
			}
			if dist < min {
				min = dist
				minL = landers[i].name + " " + landers[j].name
			}
		}
	}

	fmt.Println(maxL, minL)
}
